#include "ZoneSvr.h"
#include "sol/sol.hpp"
#include "single_progress.h"
#include "db_driver/db_driver.h"
#include "AccCon.h"
#include "game_util/publish_subscribe.h"
#include "Scene.h"
#include "player/PlayerMgr.h"

using namespace su;
using namespace std;
using namespace proto;

#define RegRpc(fun) STATIC_RUN(ZoneSvr::Ins().RegRpcFun(&ZoneSvr::fun, ZoneSvr::Ins(), #fun);)

ZoneSvr& gZoneSvr = ZoneSvr::Ins();

bool ZoneSvr::OnStart()
{
	L_COND_F(m_cfg.Init());
	L_COND_F(gSceneMgr.Init());

	Dbproxy::Ins().Init(m_cfg.dbproxyIp, m_cfg.dbproxyPort, []() { 
		LDEBUG("con dbproxy ok");
		gZoneSvr.SetReady(ReadyType::DB_CON);		
	 });
	L_COND_F(AccCon::Ins().Init());
	{
		auto OnInitOk = [this]()
		{
			auto f = [](bool isOk)
			{
				LDEBUG("reg center ok", isOk);
				gZoneSvr.SetReady(ReadyType::CENTER_CON);
			};
			m_ConToCenter.Call(f, "RegZone", m_cfg.svrId);
		};
		LDEBUG("center addr", m_cfg.centerIp.c_str(), ":", m_cfg.centerPort);
		m_ConToCenter.Init(m_cfg.centerIp.c_str(), m_cfg.centerPort, OnInitOk);
	}

	{
		auto OnInitOk = [this]()
		{
			auto f = [](bool isOk)
			{
				LDEBUG("reg rela ok", isOk);
				gZoneSvr.SetReady(ReadyType::RELA_CON);
			};
			m_ConToRela.Call(f, "RegZone", m_cfg.svrId);
		};
		m_ConToRela.Init(m_cfg.relaIp.c_str(), m_cfg.relaPort, OnInitOk);
	}
	m_fiveMinuteTimer.Start(CycleType::FIVE_MINUTE, &ZoneSvr::OnFiveMinute, this);
	m_halfHourTimer.Start(CycleType::HALF_HOUR, &ZoneSvr::OnHalfHour, this);
	return true;
}



void ZoneSvr::OnFiveMinute()
{
	// LDEBUG("on five minute");
	gPlayerMgr.OnFiveMinute();
}

void ZoneSvr::OnHalfHour()
{
	gPlayerMgr.OnHalfHour();
}

void ZoneSvr::SetReady(ReadyType flag)
{
	m_readySet[(int)flag] = true;
	if (m_readySet.all())
	{
		FireEvent<EventId::SVR_READY>();
		LDEBUG("===============================zone start ok===============================\n");
	}
}

RegRpc(UpdateDbSvrBase)
void ZoneSvr::UpdateDbSvrBase(const DbSvrBase& dbSvrBase)
{
	m_DbSvrBase = dbSvrBase;
}


bool ZoneCfg::Init()
{
	sol::state lua;
	lua.open_libraries(sol::lib::base,
		sol::lib::package,
		sol::lib::table,
		sol::lib::string);
	sol::protected_function_result r = lua.do_file("zone.lua");
	if (!r.valid())
	{
		sol::error err = r;
		std::string what = err.what();
		LERROR("zone.lua load fail error:", what);
		return false;
	}
	centerIp = lua["centerIp"];
	centerPort = lua["centerPort"];
	relaIp = lua["relaIp"];
	relaPort = lua["relaPort"];
	svrId = lua["svrId"];
	L_COND_F(svrId > 0);
	dbproxyIp = lua["dbproxyIp"];
	dbproxyPort = lua["dbproxyPort"];

	size_t accessNum = lua["accessNum"];
	LDEBUG("accessNum", accessNum);
	for (size_t i = 0; i < accessNum; i++)
	{
		AccAddr v;
		v.port = lua["access"][i + 1]["innerPort"];
		v.ip = lua["access"][i + 1]["innerIp"];
		vecAcc.push_back(v);
	}
	L_COND_F(SvrId2Type(svrId) == SvrType::Zone);
	return true;
}


namespace SvrFun {


}